#pragma once

#include "reader.h"
#include "obspattern.h"
#include "model.h"
#include "stdlib.h"
namespace Perceptron {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Threading;		
	

	/// <summary>
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form, IObserver
	{
	public:	
		model^ pModel;
		Thread ^ modelthread;
		String ^ trainFileName; // contains data
		Graphics ^ g;
		Graphics ^ temp;
		Pen ^ p;	
		Pen ^ p2;
		Pen ^ p3;
		Image ^ im;
		Bitmap ^ bm;
		array<Point,1> ^ points;
		static const int t1 = -50;
		static const int t2 = 50;
		static const int PenWidth = 4;
		static bool isDoubleBuffered = true;
		int x1,y1,x2,y2,x,y;			
		BufferedGraphicsContext^ context;
		BufferedGraphics^ buffer;
	private: System::Windows::Forms::Panel^  panel1;
	private: System::Windows::Forms::Button^  btnStopRes;
	private: System::Windows::Forms::TextBox^  txtY;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::TextBox^  txtPhi;
	private: System::Windows::Forms::TextBox^  txtWx;
	private: System::Windows::Forms::TextBox^  txtWy;
	private: System::Windows::Forms::Label^  label3;
	private: System::Windows::Forms::Label^  label4;
	private: System::Windows::Forms::Label^  label5;
	private: System::Windows::Forms::PictureBox^  pcbTemp;
	private: System::Windows::Forms::CheckBox^  ckbLearn;


	public: 
		int sleepinterval; // for the sleeping thing		
	public:
		Form1(void)
		{
			this->CheckForIllegalCrossThreadCalls = false;
			InitializeComponent();
			g = this->panel1->CreateGraphics();			
			//p = gcnew System::Drawing::Pen(System::Drawing::Color::Black);
			p = gcnew Pen(Color::Black);
			p2 = gcnew Pen(Color::Blue);
			p3 = gcnew Pen(Color::Red);
			temp = pcbTemp->CreateGraphics();									
			//
			//TODO: Add the constructor code here
			//
		}	
		void setmodel(model ^ z)
		{
			this->pModel = z;
			pModel->setSeleepInterval(1000);
		}
		virtual void update(){
			//do everything to update

			double phi = pModel->getphi();
			array<double,1> ^ wv = pModel->getWeightVector();						
			//RectangleF rf = g->ClipBounds;
			x = pModel->getX() + panel1->Width/2;
			y = panel1->Height/2 - pModel->getY();
			//g->fromim
			txtX->Text = pModel->getX() + "";
			txtY->Text = pModel->getY() + "";
			txtPhi->Text = pModel->getphi() + "";
			txtWx->Text = wv[0] + "";
			txtWy->Text = wv[1] + "";

			x1 = t1 * phi / wv[0] + panel1->Width/2;
			y1 = panel1->Height/2 - phi/wv[1] - t1 * phi / wv[1];
			x2 = t2 * phi / wv[0] + panel1->Width/2;
			y2 = panel1->Height/2 - phi/wv[1] - t2 * phi / wv[1];
			
			//Graphics ^ g  = panel1->CreateGraphics();
			g->Clear(panel1->BackColor);	
			if (bm != nullptr)	{			
				g->FromImage(bm);
				g->DrawImage(bm,20,20);
				panel1->Refresh();
			}
			//g->DrawLine(gcnew Pen(Color::Black),x1,y1,x2,y2);	

			//g->DrawEllipse(p2,x,y,PenWidth,PenWidth);
			temp->DrawEllipse(p2,x,y,PenWidth,PenWidth);				
			bm = gcnew Bitmap(panel1->Width,panel1->Height);
			pcbTemp->DrawToBitmap(bm,pcbTemp->Bounds);						
		}
		void StartModel()
		{
			//begins model execution
			this->pModel->start_learning(this->trainFileName, ckbLearn->Checked);
		}
	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
#pragma region tools
	private: System::Windows::Forms::MenuStrip^  menuStrip1;
	protected: 
	private: System::Windows::Forms::ToolStripMenuItem^  archivoToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  abrirToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  guardarToolStripMenuItem;
	private: System::Windows::Forms::ToolStripMenuItem^  salirToolStripMenuItem;
	private: System::Windows::Forms::OpenFileDialog^  openFileDialog1;
	private: System::Windows::Forms::TextBox^  txtX;

	private: System::Windows::Forms::Button^  button1;
	private: System::Windows::Forms::TrackBar^  trackBar1;




	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;
#pragma endregion
#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
			this->archivoToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->abrirToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->guardarToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->salirToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->openFileDialog1 = (gcnew System::Windows::Forms::OpenFileDialog());
			this->txtX = (gcnew System::Windows::Forms::TextBox());
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->trackBar1 = (gcnew System::Windows::Forms::TrackBar());
			this->panel1 = (gcnew System::Windows::Forms::Panel());
			this->btnStopRes = (gcnew System::Windows::Forms::Button());
			this->txtY = (gcnew System::Windows::Forms::TextBox());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->txtPhi = (gcnew System::Windows::Forms::TextBox());
			this->txtWx = (gcnew System::Windows::Forms::TextBox());
			this->txtWy = (gcnew System::Windows::Forms::TextBox());
			this->label3 = (gcnew System::Windows::Forms::Label());
			this->label4 = (gcnew System::Windows::Forms::Label());
			this->label5 = (gcnew System::Windows::Forms::Label());
			this->pcbTemp = (gcnew System::Windows::Forms::PictureBox());
			this->ckbLearn = (gcnew System::Windows::Forms::CheckBox());
			this->menuStrip1->SuspendLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->trackBar1))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pcbTemp))->BeginInit();
			this->SuspendLayout();
			// 
			// menuStrip1
			// 
			this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->archivoToolStripMenuItem});
			this->menuStrip1->Location = System::Drawing::Point(0, 0);
			this->menuStrip1->Name = L"menuStrip1";
			this->menuStrip1->Size = System::Drawing::Size(1176, 24);
			this->menuStrip1->TabIndex = 0;
			this->menuStrip1->Text = L"menuStrip1";
			// 
			// archivoToolStripMenuItem
			// 
			this->archivoToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(3) {this->abrirToolStripMenuItem, 
				this->guardarToolStripMenuItem, this->salirToolStripMenuItem});
			this->archivoToolStripMenuItem->Name = L"archivoToolStripMenuItem";
			this->archivoToolStripMenuItem->Size = System::Drawing::Size(60, 20);
			this->archivoToolStripMenuItem->Text = L"Archivo";
			this->archivoToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::archivoToolStripMenuItem_Click);
			// 
			// abrirToolStripMenuItem
			// 
			this->abrirToolStripMenuItem->Name = L"abrirToolStripMenuItem";
			this->abrirToolStripMenuItem->Size = System::Drawing::Size(116, 22);
			this->abrirToolStripMenuItem->Text = L"Abrir";
			this->abrirToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::abrirToolStripMenuItem_Click);
			// 
			// guardarToolStripMenuItem
			// 
			this->guardarToolStripMenuItem->Name = L"guardarToolStripMenuItem";
			this->guardarToolStripMenuItem->Size = System::Drawing::Size(116, 22);
			this->guardarToolStripMenuItem->Text = L"Guardar";
			// 
			// salirToolStripMenuItem
			// 
			this->salirToolStripMenuItem->Name = L"salirToolStripMenuItem";
			this->salirToolStripMenuItem->Size = System::Drawing::Size(116, 22);
			this->salirToolStripMenuItem->Text = L"Salir";
			// 
			// openFileDialog1
			// 
			this->openFileDialog1->FileName = L"openFileDialog1";
			// 
			// txtX
			// 
			this->txtX->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->txtX->Location = System::Drawing::Point(29, 316);
			this->txtX->Name = L"txtX";
			this->txtX->Size = System::Drawing::Size(40, 20);
			this->txtX->TabIndex = 1;
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(12, 243);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(75, 23);
			this->button1->TabIndex = 2;
			this->button1->Text = L"Learn";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// trackBar1
			// 
			this->trackBar1->LargeChange = 10;
			this->trackBar1->Location = System::Drawing::Point(27, 47);
			this->trackBar1->Maximum = 600;
			this->trackBar1->Name = L"trackBar1";
			this->trackBar1->Orientation = System::Windows::Forms::Orientation::Vertical;
			this->trackBar1->Size = System::Drawing::Size(45, 190);
			this->trackBar1->TabIndex = 3;
			this->trackBar1->Value = 300;
			this->trackBar1->ValueChanged += gcnew System::EventHandler(this, &Form1::trackBar1_ValueChanged);
			this->trackBar1->Scroll += gcnew System::EventHandler(this, &Form1::trackBar1_Scroll);
			// 
			// panel1
			// 
			this->panel1->BackColor = System::Drawing::SystemColors::Info;
			this->panel1->Location = System::Drawing::Point(162, 27);
			this->panel1->Name = L"panel1";
			this->panel1->Size = System::Drawing::Size(500, 500);
			this->panel1->TabIndex = 6;
			// 
			// btnStopRes
			// 
			this->btnStopRes->Enabled = false;
			this->btnStopRes->Location = System::Drawing::Point(13, 273);
			this->btnStopRes->Name = L"btnStopRes";
			this->btnStopRes->Size = System::Drawing::Size(75, 23);
			this->btnStopRes->TabIndex = 7;
			this->btnStopRes->Text = L"Stop";
			this->btnStopRes->UseVisualStyleBackColor = true;
			this->btnStopRes->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
			this->btnStopRes->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::btnStopRes_MouseDown);
			// 
			// txtY
			// 
			this->txtY->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->txtY->Location = System::Drawing::Point(95, 316);
			this->txtY->Name = L"txtY";
			this->txtY->Size = System::Drawing::Size(40, 20);
			this->txtY->TabIndex = 8;
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Location = System::Drawing::Point(10, 318);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(17, 13);
			this->label1->TabIndex = 9;
			this->label1->Text = L"X:";
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(78, 318);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(17, 13);
			this->label2->TabIndex = 10;
			this->label2->Text = L"Y:";
			// 
			// txtPhi
			// 
			this->txtPhi->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->txtPhi->Location = System::Drawing::Point(75, 358);
			this->txtPhi->Name = L"txtPhi";
			this->txtPhi->Size = System::Drawing::Size(60, 20);
			this->txtPhi->TabIndex = 11;
			// 
			// txtWx
			// 
			this->txtWx->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->txtWx->Location = System::Drawing::Point(75, 384);
			this->txtWx->Name = L"txtWx";
			this->txtWx->Size = System::Drawing::Size(59, 20);
			this->txtWx->TabIndex = 12;
			// 
			// txtWy
			// 
			this->txtWy->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
			this->txtWy->Location = System::Drawing::Point(75, 410);
			this->txtWy->Name = L"txtWy";
			this->txtWy->Size = System::Drawing::Size(58, 20);
			this->txtWy->TabIndex = 13;
			// 
			// label3
			// 
			this->label3->AutoSize = true;
			this->label3->Location = System::Drawing::Point(41, 360);
			this->label3->Name = L"label3";
			this->label3->Size = System::Drawing::Size(28, 13);
			this->label3->TabIndex = 14;
			this->label3->Text = L"PHI:";
			// 
			// label4
			// 
			this->label4->AutoSize = true;
			this->label4->Location = System::Drawing::Point(41, 386);
			this->label4->Name = L"label4";
			this->label4->Size = System::Drawing::Size(26, 13);
			this->label4->TabIndex = 15;
			this->label4->Text = L"Wx:";
			// 
			// label5
			// 
			this->label5->AutoSize = true;
			this->label5->Location = System::Drawing::Point(41, 412);
			this->label5->Name = L"label5";
			this->label5->Size = System::Drawing::Size(26, 13);
			this->label5->TabIndex = 16;
			this->label5->Text = L"Wy:";
			// 
			// pcbTemp
			// 
			this->pcbTemp->BackColor = System::Drawing::SystemColors::Info;
			this->pcbTemp->Location = System::Drawing::Point(668, 30);
			this->pcbTemp->Name = L"pcbTemp";
			this->pcbTemp->Size = System::Drawing::Size(500, 500);
			this->pcbTemp->TabIndex = 17;
			this->pcbTemp->TabStop = false;
			// 
			// ckbLearn
			// 
			this->ckbLearn->AutoSize = true;
			this->ckbLearn->Checked = true;
			this->ckbLearn->CheckState = System::Windows::Forms::CheckState::Checked;
			this->ckbLearn->Location = System::Drawing::Point(29, 464);
			this->ckbLearn->Name = L"ckbLearn";
			this->ckbLearn->Size = System::Drawing::Size(49, 17);
			this->ckbLearn->TabIndex = 18;
			this->ckbLearn->Text = L"learn";
			this->ckbLearn->UseVisualStyleBackColor = true;
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(1176, 529);
			this->Controls->Add(this->ckbLearn);
			this->Controls->Add(this->pcbTemp);
			this->Controls->Add(this->label5);
			this->Controls->Add(this->label4);
			this->Controls->Add(this->label3);
			this->Controls->Add(this->txtWy);
			this->Controls->Add(this->txtWx);
			this->Controls->Add(this->txtPhi);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->txtY);
			this->Controls->Add(this->btnStopRes);
			this->Controls->Add(this->panel1);
			this->Controls->Add(this->trackBar1);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->txtX);
			this->Controls->Add(this->menuStrip1);
			this->MainMenuStrip = this->menuStrip1;
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->FormClosed += gcnew System::Windows::Forms::FormClosedEventHandler(this, &Form1::Form1_FormClosed);
			this->menuStrip1->ResumeLayout(false);
			this->menuStrip1->PerformLayout();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->trackBar1))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pcbTemp))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void abrirToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
			
				String ^x, ^y;
			
	            openFileDialog1->ShowDialog();
				trainFileName = openFileDialog1->FileName;											
			 }
private: System::Void archivoToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
			 			
			 btnStopRes->Enabled = true;
			 this->modelthread = gcnew Thread(gcnew ThreadStart(this,&Form1::StartModel));
			 modelthread->Start();			 			 

		 }
private: System::Void trackBar1_Scroll(System::Object^  sender, System::EventArgs^  e) {
		 }
private: System::Void trackBar1_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
						 
			 pModel->setSeleepInterval(trackBar1->Value);
		 }
private: System::Void Form1_FormClosed(System::Object^  sender, System::Windows::Forms::FormClosedEventArgs^  e) {			
			 if (modelthread != nullptr) 
				 modelthread->Abort(); 			 
		 }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
			 if (modelthread->IsAlive){
				 if (btnStopRes->Text->Equals("Stop"))
				 {
					 modelthread->Suspend();
					 btnStopRes->Text = "Resume";
				 }else{ 
					 modelthread->Resume();
					 btnStopRes->Text = "Stop";
				 }
			 }
		 }
private: System::Void btnStopRes_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {			
		 }
};
}

